﻿namespace System.ServiceModel.DomainServices.Client
{
    using System;
    using System.Collections.Specialized;

    internal class WeakCollectionChangedListener
    {
        private INotifyCollectionChanged _source;
        private WeakReference _weakListener;

        private WeakCollectionChangedListener(INotifyCollectionChanged source, ICollectionChangedListener listener)
        {
            this._source = source;
            this._source.CollectionChanged += new NotifyCollectionChangedEventHandler(this.SourceCollectionChanged);
            this._weakListener = new WeakReference(listener);
        }

        public static WeakCollectionChangedListener CreateIfNecessary(object source, ICollectionChangedListener listener)
        {
            INotifyCollectionChanged changed = source as INotifyCollectionChanged;
            if (changed != null)
            {
                return new WeakCollectionChangedListener(changed, listener);
            }
            return null;
        }

        internal void Disconnect()
        {
            if (this._source != null)
            {
                this._source.CollectionChanged -= new NotifyCollectionChangedEventHandler(this.SourceCollectionChanged);
                this._source = null;
                this._weakListener = null;
            }
        }

        private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (this._weakListener != null)
            {
                ICollectionChangedListener target = this._weakListener.Target as ICollectionChangedListener;
                if (target != null)
                {
                    target.OnCollectionChanged(sender, e);
                }
                else
                {
                    this.Disconnect();
                }
            }
        }
    }
}

